package com.bingxue.edu.management.shop.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bingxue.edu.common.config.FuiouPayProperties;
import com.bingxue.edu.common.enums.OperateSourceEnum;
import com.bingxue.edu.common.enums.PayTypeEnum;
import com.bingxue.edu.common.util.FuiouPaySignUtil;
import com.bingxue.edu.management.shop.model.entity.Order;
import com.bingxue.edu.management.shop.model.req.OrderOfflinePayReq;
import com.bingxue.edu.management.shop.model.req.OrderOnlinePayReq;
import com.bingxue.edu.management.shop.model.req.OrderPayCompleteReq;
import com.bingxue.edu.management.shop.service.OrderService;
import com.bingxue.edu.framework.common.model.Response;
import com.bingxue.edu.framework.common.util.CheckUtils;
import com.bingxue.edu.framework.security.ApiResource;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

/**
 * 支付接口
 *
 * @author panbo
 * @since 2024/9/2
 */
@Slf4j
@Tag(name = "支付接口")
@RestController
@RequestMapping("/shop/pay")
@RequiredArgsConstructor
public class PayController {

    private final FuiouPayProperties fuiouPayProperties;
    private final OrderService orderService;

    @SaIgnore
    @Operation(description = "富有支付回调接口")
    @PostMapping("/callback/fuiou")
    public Response<Void> onlinePayCallback(HttpServletRequest request) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
        String body = IoUtil.read(reader);
        log.info("支付回调body: {}", body);
        JSONObject result = JSONUtil.parseObj(body);
        CheckUtils.throwIfNotEqual(result.get("resp_code"), "0000", "富友支付回调出错, body: {} ", body);
        String message = FuiouPaySignUtil.decryptByRsaPri(result.getStr("message"), fuiouPayProperties.getMchntPrivateKey(), "GBK");
        orderService.completeOnlinePay(new JSONObject(message));
        return Response.success();
    }

    @Operation(description = "刷新支付结果")
    @PostMapping("/result/refresh")
    public Response<Void> refreshPayResult(@RequestParam @NotNull String orderId) {
        Order order = orderService.getById(orderId);
        orderService.refreshPayResult(order);
        return Response.success();
    }

    @Operation(description = "线上支付")
    @PostMapping("/online")
    public Response<Object> onlinePay(@RequestBody @Validated OrderOnlinePayReq req) {
        return Response.success(orderService.onlinePay(req));
    }

    @Operation(description = "线下完成订单支付接口")
    @ApiResource(" edu:enroll:verify")
    @PostMapping("/offline")
    public Response<Void> offlinePay(@RequestBody @Validated OrderOfflinePayReq req) {
        OrderPayCompleteReq orderPayCompleteReq = new OrderPayCompleteReq();
        orderPayCompleteReq.setOrderId(req.getOrderId());
        orderPayCompleteReq.setFinAccountId(req.getFinAccountId());
        orderPayCompleteReq.setPayType(PayTypeEnum.OFFLINE);
        orderPayCompleteReq.setPayTime(req.getPayTime() == null ? LocalDateTime.now() : req.getPayTime());
        orderPayCompleteReq.setOperateSource(OperateSourceEnum.BACKEND);
        orderService.completeOrder(orderPayCompleteReq);
        return Response.success();
    }

    @Operation(description = "线下完成订单退费接口")
    @ApiResource(" edu:enroll:verify")
    @PostMapping("/refund")
    public Response<Void> completeRefund(@RequestBody @Validated OrderPayCompleteReq req) {
//        orderService.completePay(req);
        return Response.success();
    }
}
